/**
 * @(#)UserAccount.java        1.0 2/15/12
 * 
 * Copyright (c) 2012 public static droid main
 * Georgia Institute of Technology, Atlanta, GA
 * All rights reserved.
 */

package edu.gatech.oad.publicstaticdroidmain.taskmanager.model;

import java.util.Date;

import edu.gatech.oad.publicstaticdroidmain.taskmanager.persistence.DataSourceInterface;

/**
 * Abstraction of an account in the TaskManager.  Allows for retrieval
 * and editing of user settings and interaction with a user's Tasks.
 * Also includes facilities for filtering a user's Tasks.
 * 
 * @version 1.0 2/27/12
 * @author Daniel Hull
 *
 */
public class UserAccount {
    private DataSourceInterface database;
    private String username;
    
    /**
     * Constructs a new UserAccount representing the account with the
     * specified username that will operate on the specified database. 
     * 
     * @param database the database from which user information will be
     * 		retrieved
     * @param username the username of the account to generate
     */
    public UserAccount(DataSourceInterface database, String username) {
	this.database = database;
	this.username = username;
    }
    
    /**
     * Returns the username of this account.
     * 
     * @return the username of this account
     */
    public String getUsername() {
	return username;
    }
    
    /**
     * Returns the real name of the person who owns this account.
     * 
     * @return the real name of the person who owns this account
     */
    public String getRealName() {
	return database.getRealName(username);
    }
    
    /**
     * Returns the email address of the person who owns this account.
     * 
     * @return the email address of the person who owns this account
     */
    public String getEmailAddress() {
	return database.getEmailAddress(username);
    }
    
    /**
     * Sets the username of this account to the specified value.
     * 
     * @param newUsername the new username
     */
    public void setUsername(String newUsername) {
	database.updateUsername(username, newUsername);
	this.username = newUsername;
    }
    
    /**
     * Sets the password of this account to the specified new password.
     * 
     * @param oldPassword this account's current password
     * @param newPassword the new password to set
     */
    public void setPassword(String oldPassword, String newPassword) {
	database.updatePassword(username, oldPassword, newPassword);
    }
    
    /**
     * Sets the real name of the person who owns this account to the
     * specified name.
     * 
     * @param newRealName the new real name
     */
    public void setRealName(String newRealName) {
	database.updateRealName(username, newRealName);
    }
    
    /**
     * Sets the email address of the person who owns this account to
     * the specified address.
     * 
     * @param newEmailAddress the new email address
     */
    public void setEmailAddress(String newEmailAddress) {
	database.updateEmailAddress(username, newEmailAddress);
    }
    
    /**
     * Adds the specified category to this UserAccount.
     * 
     * @param category the name of the category to add
     * @return true if the category was added successfully; false if the
     * 		category already exists
     */
    public boolean addCategory(String category) {
	return database.addCategory(username, category);
    }
    
    /**
     * Changes the name of the specified category to the specified new
     * name.  If the new name is already taken by another category,
     * the Tasks in the old category will be moved to the new
     * category.
     * 
     * @param oldName the name of the category to edit
     * @param newName the new name of the category
     * @return true if the category's name was successfully changed; false
     * 		if the category does not exist
     */
    public boolean editCategoryName(String oldName, String newName) {
	return database.updateCategoryName(username, oldName, newName);
    }
    
    /**
     * Removes the specified category from this UserAccount if it exists.
     * 
     * @param category the name of the category to remove
     * @return true if the category was successfully removed; false if the
     * 		specified category does not exist
     */
    public boolean removeCategory(String category, String replacement) {
	return database.removeCategory(username, category, replacement);
    }
    

    /**
     * Returns the names of the categories in this UserAccount.
     * 
     * @return an array containing the names of the categories in
     * 		this UserAccount
     */
    public String[] getCategories() {
	return database.getCategories(username);
    }
    
    /**
     * Returns the Tasks in the specified category in this UserAccount.
     * 
     * @param category the category of Tasks to retrieve
     * @return an array containing the Tasks in the specified category; null
     * 		if the specified category does not exist
     */
    public Task[] getTasksInCategory(String category) {
	return database.getTasksInCategory(username, category);
    }
    
    /**
     * Returns the Tasks with the specified completion status in this 
     * UserAccount.
     * 
     * @param completionStatus the completion status of the Tasks to
     * 		retrieve
     * @return an array containing the Tasks in this account with the
     * 		specified completion status
     */
    public Task[] getTasksWithCompletionStatus(boolean completionStatus) {
	return database.getTasksWithCompletionStatus(username, completionStatus);
    }
    
    /**
     * Returns the Tasks whose due dates on or after the specified Date
     * in this UserAccount.
     * 
     * @param date the dividing Date
     * @return an array of Tasks in this account whose due dates are on 
     * 		or after the specified date
     */
    public Task[] getTasksAfterDate(Date date) {
	return database.getTasksAfterDate(username, date);
    }
    
    /**
     * Adds the specified Task to this UserAccount if one with the
     * same ID does not already exist.
     * 
     * @param task the Task to add
     * @return true if the Task was successfully added; false if a Task with
     * 		the same ID as the specified Task already exists in the account
     */
    public boolean addTask(Task task) {
	return database.addTask(username, task);
    }
    
    /**
     * Updates the specified Task's information in this UserAccount.  If
     * you change the information in a Task object, call this method to save
     * the changes in this UserAccount.
     * 
     * @param task the Task to update
     * @return true if the specified Task was successfully updated; false if
     * 		the specified Task does not exist in this UserAccount
     */
    public boolean updateTask(Task task) {
	return database.updateTask(username, task);
    }
    
    /**
     * Removes the specified Task from this UserAccount if it exists.
     * 
     * @param task the Task to remove
     * @return true if the Task was successfully removed; false if the Task
     * 		does not exist in this UserAccount
     */
    public boolean removeTask(Task task) {
	return database.removeTask(username, task.getId());
    }
    
    /**
     * Returns the Task object in this UserAccount with the specified ID.
     * 
     * @param id the ID of the Task to retrieve
     * @return the Task object in this UserAccount with the specified ID; 
     * 		null if a Task with the specified ID does not exist in this 
     * 		UserAccount
     */
    public Task getTask(long id) {
	return database.getTask(username, id);
    }
    
    /**
     * Returns all of the Tasks in this UserAccount.
     * 
     * @return an array containing all of the Tasks in this UserAccount
     */
    public Task[] getAllTasks() {
	return database.getAllTasks(username);
    }
}
